<template>
  <div class="upload">
    <el-upload
      v-loading="isLoading"
      class="single-img-uploader"
      :class="customClass"
      action="/"
      :show-file-list="false"
      :on-success="handleSuccess"
      :on-error="handleError"
      :on-progress="handleUploadProcess"
      :before-upload="validateImg"
      :http-request="httpRequest"
      :disabled="imgDisabled || isLoading"
    >
      <div v-if="imageUrl" slot="trigger">
        <img :src="imageUrl" class="avatar" :class="customClass">
        <div class="hover-action" />
      </div>
      <template v-if="imageUrl">
        <div class="img-uploader__panel">
          <div class="name">{{ currentFile.name }}</div>
          <div class="edit-btn">
            <i class="el-icon-zoom-in" @click.prevent="handleZoonIn" />
            <i class="el-icon-delete" @click.prevent="clear" />
          </div>
        </div>
      </template>
      <i v-else class="el-icon-plus img-uploader-icon" :class="customClass" />
      <div slot="tip" class="el-upload__tip">
        {{ uploadTips }}
      </div>
    </el-upload>
    <el-dialog
      class="single-img-uploader__dialog"
      append-to-body
      :visible.sync="dialogVisible"
    >
      <el-image width="100%" :src="imageUrl" alt="" />
    </el-dialog>
    <slot />
  </div>
</template>
<script>
import ImgUploadMixin from '../mixins/ImgUploadFn'
import SectionLoadingMixin from 'modules/mixins/section-loading'
export default {
  mixins: [ImgUploadMixin, SectionLoadingMixin],
  props: {
    value: {
      type: String,
      default: ''
    },
    imgDisabled: Boolean,
    config: {
      type: Object,
      default() {
        return {}
      }
    }
  },
  data() {
    return {
      imageUrl: '',
      currentFile: {},
      dialogVisible: false,
      uploadPercent: 0
    }
  },
  watch: {
    value(val) {
      if (this.imageUrl !== val) {
        this.imageUrl = val
      }
    }
  },
  mounted() {
    this.init()
  },
  methods: {
    init() {
      this.imageUrl = this.value
    },
    async validateImg(file) {
      console.log('validateImg', file)
      let errorMsg = ''
      const typeLimit = this.typeLimit(file)
      // 类型不对后面都没有验收的必要了
      if (typeLimit) {
        this.$message.error(typeLimit)
        return Promise.reject()
      }

      const sizeLimit = this.sizeLimit(file)
      sizeLimit && (errorMsg += sizeLimit)

      const widthHeightLimit = await this.widthHeightLimit(file)
      widthHeightLimit && (errorMsg += widthHeightLimit)

      // 自定义事件一定要在获取宽高之后
      const validateMsg = this.customLimit(file)
      validateMsg && (errorMsg += validateMsg)

      if (errorMsg) {
        this.$message.error(errorMsg)
        return Promise.reject()
      }
      return true
    },
    handleSuccess(res, file) {
      if (res.success && res.data) {
        this.$message.success('上传成功!')
        this.imageUrl = res.data || this.createImgUrl(file.raw)
        this.currentFile = file
        this.$emit('success', this.imageUrl)
        this.$emit('input', this.imageUrl)
      }
    },
    handleError() {
      this.$message.error('图片上传出现问题，请尝试重新上传！')
      this.clear()
    },
    clear() {
      this.imageUrl = ''
      this.$emit('input', '')
      this.currentFile = {}
    },
    submit() {
      this.$emit('input', this.imageUrl)
      return this.imageUrl
    },
    handleZoonIn() {
      this.dialogVisible = true
    },
    handleUploadProcess(event, file) {
      console.log('upload', file)
    },
    async httpRequest(data) {
      this.loading()
      const file = new FormData()
      file.append('file', data.file)
      let res
      try {
        if (Object.keys(this.config).length === 0) {
          res = await upload(file)
        } else {
          res = await upload(file, this.config)
        }

        if (res.success) {
          return res
        } else {
          this.handleError()
        }
      } finally {
        this.loaded()
      }
    }
  }
}
</script>
